import java.util.concurrent.locks.ReentrantLock;

class ex02c {

public static ReentrantLock mutex = new ReentrantLock();
public static Object mutexObj = new Object();

public static boolean call() throws Exception
{
	throw new Exception();
}

public static void ex02ca() throws Exception
{
// [[ex02ca]]
mutex.lock();
try {
	call();
} finally {
	mutex.unlock();
}
// END
}

public static void ex02cb() throws Exception
{
// [[ex02cb]]
synchronized(mutexObj) {
	call();
}
// END
}

// the buffer is for syntax-checking only
public static class Buffer {
	public boolean full() {
		return true;
	}
	public void append(byte[] data)
	{
	}
};
public static Buffer buffer = new Buffer();
public static byte[] read()
{
	return new byte[0];
}

public static void ex02cc()
{
// [[ex02cc]]
// DEBUG descr Appending data to a buffer, before synchronization.
while(!buffer.full()) {
	byte [] data = read();
	buffer.append(data);
}
// END
}

public static void ex02cd()
{
// [[ex02cd]]
// DEBUG descr Appending data to a buffer, simple but incorrect synchronization.
synchronized(buffer) {
	while(!buffer.full()) {
		byte [] data = read();
		buffer.append(data);
	}
}
// END
}

public static void ex02ce()
{
// [[ex02ce]]
// DEBUG descr Appending data to a buffer, synchronization released while sleeping.
while (true) {
	synchronized(buffer) {
		if (buffer.full())
			break;
	}
	byte [] data = read();
	synchronized(buffer) {
		buffer.append(data);
	}
}
// END
}

public static void ex02cf()
{
// [[ex02cf]]
// DEBUG descr Appending data to a buffer, synchronized once per loop iteration.
boolean done;
synchronized(buffer) {
	done = buffer.full();
}
while (!done) {
	byte [] data = read();
	synchronized(buffer) {
		buffer.append(data);
		done = buffer.full();
	}
}
// END
}

public static void ex02cg()
{
// [[ex02cg]]
// DEBUG descr Appending data to a buffer, synchronization with a ReentrantLock.
ReentrantLock mutex = new ReentrantLock();

try {
	mutex.lock();
	while(!buffer.full()) {
		byte [] data = null;
		try {
			mutex.unlock();
			data = read();
		} finally {
			mutex.lock();
		}
		if (data != null)
			buffer.append(data);
	}
} finally {
	mutex.unlock();
}
// END
}


public static void main(String[] args) throws Exception
{
	// ex02ca();
	// ex02cb();
	ex02cc();
	ex02cd();
	ex02ce();
	ex02cf();
	ex02cg();
}
};
